/**
Nectarine Utility Project is a software interface for the web system 'demovibes'
Copyright (C) 2010  Alexandre LAURENT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

website: http://code.google.com/p/nectarine-utility-project/
e-mail: lw.demoscene@gmail.com
**/

#include "playerwidget.h"

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QProgressBar>
#include <QImage>
#include <QPushButton>
#include <QComboBox>
#include <QCheckBox>
#include <QGroupBox>
#include <QIcon>
#include <QStyle>

#include <QString>
#include <QMap>

#include <Phonon/BackendCapabilities>
#include <Phonon/Effect>

#include <QResizeEvent>

#include <QDebug>

#include "utils.h"
#include "globals.h"

PlayerWidget :: PlayerWidget(Phonon::MediaObject* const pMediaObject, Phonon::AudioOutput* const pAudioOutput, Phonon::Path* const pAudioPath, QWidget *parent)
    :QWidget(parent),baseColour(234,162,0),pAudioPath(pAudioPath)
{
    pMainGrid = new QVBoxLayout(this);

    QPalette playerPalette;
    playerPalette.setBrush(QPalette::WindowText, QColor(47,125,245));

    pScreenImageLabel = new QLabel(this);
    pScreenImageLabel->setStyleSheet("border-image:url(./data/player_ui.png) ; border-width:3px ; font: 12px;");
    pScreenImageLabel->setText("<b><center>No media</center></b>");
    pScreenImageLabel->setPalette(playerPalette);
    pScreenImageLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
    pScreenImageLabel->setMaximumHeight(100);

    pBufferGrid = new QHBoxLayout();
    pBufferLabel = new QLabel(tr("Buffer:"),this);
    pBufferProgressBar = new QProgressBar(this);
    pBufferProgressBar->setRange(0,100);

    pButtonGrid = new QHBoxLayout();

    pProgressionSlider = new Phonon::SeekSlider(pMediaObject,this);

    pProgressionSlider->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Maximum);

    pPlayButton = new QPushButton(this);
    playIcon = style()->standardIcon(QStyle::SP_MediaPlay);
    pauseIcon = style()->standardIcon(QStyle::SP_MediaPause);
    pPlayButton->setIcon(playIcon);

    pStopButton = new QPushButton(this);
    pStopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop));

    pVolumeSlider = new Phonon::VolumeSlider(pAudioOutput,this);

    pPlayButton->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Maximum);
    pStopButton->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Maximum);
    pVolumeSlider->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Maximum);

    //pEffectAction = new QAction(tr("Effects"),this);
    pEffectCB = new QComboBox(this);

    {
        QList<Phonon::EffectDescription> effectDescriptions = Phonon::BackendCapabilities::availableAudioEffects();
        foreach(Phonon::EffectDescription effectDescription, effectDescriptions)
        {
            pEffectCB->addItem(QIcon(ICONSDIR + QString("disabled.png")),effectDescription.name());
            listPEffects.push_back(new Phonon::Effect(effectDescription,this));
        }
    }

    pEnableCheckBox = new QCheckBox(tr("?Enable"),this);
    pEnableCheckBox->setLayoutDirection(Qt::RightToLeft);

    if ( listPEffects.size() != 0 )
    {
        pEffectWidget = new Phonon::EffectWidget(listPEffects[0],this);
    }
    else
    {
        pEffectCB->addItem("No Effect available");
        pEffectCB->setEnabled(false);
    }

    pMainGrid->addWidget(pScreenImageLabel);
    pMainGrid->addLayout(pBufferGrid);
    pBufferGrid->addWidget(pBufferLabel);
    pBufferGrid->addWidget(pBufferProgressBar);
    pMainGrid->addWidget(pProgressionSlider);
    pMainGrid->addLayout(pButtonGrid);
    pButtonGrid->addWidget(pPlayButton);
    pButtonGrid->addWidget(pStopButton);
    pButtonGrid->addWidget(pVolumeSlider);
    pMainGrid->addWidget(pEffectCB);
    pMainGrid->addWidget(pEnableCheckBox);
    pMainGrid->addWidget(pEffectWidget);

    connect(pPlayButton, SIGNAL(clicked()), this, SLOT(clickedPlayPauseButton()));
    connect(pStopButton, SIGNAL(clicked()), this, SLOT(clickedStopButton()));
    connect(pMediaObject, SIGNAL(bufferStatus(int)), pBufferProgressBar, SLOT(setValue(int)));
    connect(pEffectCB, SIGNAL(currentIndexChanged(int)), this, SLOT(displayEffectWidget(int)));
    connect(pEnableCheckBox, SIGNAL(toggled(bool)), this, SLOT(toogleEffect(bool)));

    qDebug() << "PlayerWidget created";
}

PlayerWidget :: ~PlayerWidget(void)
{
    for ( QList<Phonon::Effect*>::const_iterator itEffect = listPEffects.begin() ; itEffect != listPEffects.end() ; ++itEffect)
    {
        delete (*itEffect);
    }

    listPEffects.clear();

    qDebug() << "PlayerWidget deleted";
}

QImage PlayerWidget :: renderScreen(const QColor& baseColor)
{
    QImage screenImage(this->width()-20,250,QImage::Format_RGB32);

    qDebug() << "PlayerWidget :: renderScreen (" << baseColor << ")";

    for ( int y = 0 ; y < screenImage.height() ; y++ )
    {
        for ( int x = 0 ; x < screenImage.width() ; x++ )
        {
            screenImage.setPixel(x,y,baseColor.rgb());
        }
    }

    return screenImage;
}

void PlayerWidget :: tooglePlayPauseState(void)
{
    qDebug() << "PlayerWidget :: tooglePlayPauseState (" << isPlaying << ")";

    pStopButton->setEnabled(true);

    if ( !isPlaying )
    {
        pPlayButton->setIcon(pauseIcon);
        isPlaying = true;
    }
    else
    {
        pPlayButton->setIcon(playIcon);
        isPlaying = false;
    }
}

void PlayerWidget :: setStopState(void)
{
    qDebug() << "PlayerWidget :: setStopState";

    pStopButton->setEnabled(false);
    pPlayButton->setIcon(playIcon);
    isPlaying = false;

    emit stopStateSignal();
}

void PlayerWidget :: clickedPlayPauseButton(void)
{
    qDebug() << "PlayerWidget :: clickedPlayPauseButton";

    // this->tooglePlayPauseState();
    emit tooglePlayPauseStateSignal();
    /*
    if ( !isPlaying )
    {
        emit playStateSignal();
    }
    else
    {
        emit pauseStateSignal();
    }
    */
}

void PlayerWidget :: clickedStopButton(void)
{
    qDebug() << "PlayerWidget :: clickedStopButton";

    // this->setStopState();
    emit stopStateSignal();
}

void PlayerWidget :: displayEffectWidget(int effectIndex)
{
    qDebug() << "PlayerWidget :: displayEffectWidget (" << effectIndex << ")";

    pMainGrid->removeWidget(pEffectWidget);

    delete pEffectWidget;
    pEffectWidget = new Phonon::EffectWidget(listPEffects[effectIndex],this);

    pMainGrid->addWidget(pEffectWidget);

    if ( pAudioPath->effects().contains(listPEffects[effectIndex]) )
    {
        pEnableCheckBox->setChecked(true);
    }
    else
    {
        pEnableCheckBox->setChecked(false);
    }
}

void PlayerWidget :: toogleEffect(bool isEnabled)
{
    qDebug() << "PlayerWidget :: toogleEffect (" << isEnabled << ")";

    if ( isEnabled )
    {
        pAudioPath->insertEffect(listPEffects[pEffectCB->currentIndex()]);
        pEffectCB->setItemIcon(pEffectCB->currentIndex(),QIcon(ICONSDIR + QString("enabled.png")));
    }
    else
    {
        pAudioPath->removeEffect(listPEffects[pEffectCB->currentIndex()]);
        pEffectCB->setItemIcon(pEffectCB->currentIndex(),QIcon(ICONSDIR + QString("disabled.png")));
    }
}

void PlayerWidget :: updateInfo(const QMap<QString, QString>& metaData, const QString& url)
{
    qDebug() << "PlayerWidget :: updateInfo " << metaData.keys();

    pScreenImageLabel->setText(metaData.value("TITLE") + QString("\n") +
                               metaData.value("ARTIST") + QString("\n") +
                               QString("Bitrate: %1kbps").arg(metaData.value("BITRATE").toInt()/1000) + QString("\n") +
                               url);
}
